package com.fushenlan.epidemicControl.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.fushenlan.commons.GeneralResponse;
import com.fushenlan.epidemicControl.service.AreaService;
import com.fushenlan.po.Area;
import com.fushenlan.po.BuildingInfoDO;
import com.fushenlan.po.NeighborhoodInfoDO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @Author XUJIN
 * @DATE 2022/4/21
 * @PACKAGE_NAME com.fushenlan.epidemicControl.controller
 * @VERSION 1.0
 * 国标数据信息管理控制器
 */
@Slf4j
@RestController
@RequestMapping("area")
@Api(value = "国标数据信息管理控制器", description = "国标数据信息管理控制器", tags = "area-controller")
public class AreaController {

    @Autowired
    private AreaService areaService;

    @Autowired
    private StringRedisTemplate redisTemplate;

    private static final String AREA_KEY = "area:";
    private static final String BUILD_KEY = "build:";
    private static final String NEIGHBORHOOD_KEY = "neighborhood:";

    @GetMapping("getSubAreaByIdAndDeep")
    @ApiOperation(value = "根据区域id获取下级行政区域", notes = "根据id获取下级行政区域")
    public GeneralResponse<?> getSubArea(@ApiParam(value = "区域id 获取所有省 填0", required = true) @RequestParam String id, @RequestParam String deep) {
        Area area = new Area();

        if ("all".equals(id)) {
            List<Area> arrayList = new ArrayList<>();
            Set<String> keys = redisTemplate.keys(AREA_KEY + deep + "-*");
            if (keys != null && keys.size() > 0) {
                List<String> list = redisTemplate.opsForValue().multiGet(keys);
                if (list != null && list.size() > 0) {
                    list.forEach(str -> {
                        List<Area> areas = JSONUtil.toList(JSONUtil.parseArray(str), Area.class);
                        arrayList.addAll(areas);
                    });
                    log.info("从redis中获取到了所有层级数据");
                    return GeneralResponse.success(arrayList);
                }
            }
        }
        Object area1 = redisTemplate.opsForValue().get(AREA_KEY + deep + "-" + id);
        if ("-1".equals(redisTemplate.opsForValue().get("area" + deep + "-" + id))) {
            log.info("redis中缓存-1");
            return GeneralResponse.fail("-1", "未查询到信息", "");
        }
        if (!Objects.isNull(area1)) {
            //解析
            List<Area> areaList = JSONUtil.toList(JSONUtil.parseArray(area1), Area.class);
            log.info("从redis中获取到了行政区域等数据");
            return GeneralResponse.success(areaList);
        }
        //查询数据
        if (!"all".equals(id)) {
            area.setPid(id);
            area.setDeep(deep);
        } else {
            area.setDeep(deep);
        }
        List<Area> list = areaService.findList(area);
        if (CollectionUtil.isEmpty(list)) {
            redisTemplate.opsForValue().set("area" + deep + "-" + id, "-1", 5L, TimeUnit.SECONDS);
            return GeneralResponse.fail("-1", "未查询到省市区信息", "");
        }
        Map<String, List<Area>> map = list.stream().sorted(Comparator.comparingInt(a -> Integer.parseInt(a.getPid()))).collect(Collectors.groupingBy(a -> a.getDeep() + "-" + a.getPid()));
        List<Area> arrayList = new ArrayList<>();
        map.forEach((deepAndPid, value) -> {
            redisTemplate.opsForValue().set(AREA_KEY + deepAndPid, JSONUtil.toJsonStr(value), 1L, TimeUnit.HOURS);
            arrayList.addAll(value);
        });
        return GeneralResponse.success(arrayList);
    }

    @GetMapping("getNeighborhood")
    @ApiOperation(value = "获取所属居委", notes = "获取所属居委")
    public GeneralResponse<?> getNeighborhood(@ApiParam(value = "街道id 获取所属居委", required = true) @RequestParam String streetCode) {
        if (StrUtil.isBlank(streetCode)) {
            return GeneralResponse.fail("-1", "请先选择所属街道", "");
        }
        Object neighborhood = redisTemplate.opsForValue().get(NEIGHBORHOOD_KEY + streetCode);
        if (neighborhood != null) {
            List<NeighborhoodInfoDO> list = JSONUtil.toList(JSONUtil.parseArray(neighborhood), NeighborhoodInfoDO.class);
            List<Map<String, Object>> collect = list.stream().map(info -> {
                Map<String, Object> hashMap = new HashMap<>();
                hashMap.put("id", info.getId());
                hashMap.put("neighborhoodName", info.getNeighborhoodName());
                return hashMap;
            }).collect(Collectors.toList());
            log.info("从redis中获取到了居委数据");
            return GeneralResponse.success(collect);
        }
        List<NeighborhoodInfoDO> list = areaService.queryListByStreetCode(streetCode);
        if (CollectionUtil.isEmpty(list)) {
            return GeneralResponse.fail("-1", "未查询到所属居委信息", "");
        }
        Map<String, List<NeighborhoodInfoDO>> map = list.stream().collect(Collectors.groupingBy(NeighborhoodInfoDO::getStreetCode));
        map.forEach((k, v) -> redisTemplate.opsForValue().set(NEIGHBORHOOD_KEY + k, JSONUtil.toJsonStr(v), 1L, TimeUnit.HOURS));

        return GeneralResponse.success(list.stream().map(info -> {
            Map<String, Object> hashMap = new HashMap<>();
            hashMap.put("id", info.getId());
            hashMap.put("neighborhoodName", info.getNeighborhoodName());
            return hashMap;
        }).collect(Collectors.toList()));
    }

    @GetMapping("getBuildById")
    @ApiOperation(value = "获取小区楼栋室号等", notes = "获取小区楼栋室号等")
    public GeneralResponse<?> getStreet(@ApiParam(value = "pid 获取小区楼栋室号等,当deep=1时，id为居委id", required = true) @RequestParam String id, @RequestParam String deep) {
        if (StrUtil.hasBlank(id, deep)) {
            return GeneralResponse.fail("-1", "请先选择所属居委", "");
        }
        if ("-1".equals(redisTemplate.opsForValue().get("build" + deep + "-" + id))) {
            log.info("redis中缓存-1");
            return GeneralResponse.fail("-1", "未查询到信息", "");
        }
        Object build = redisTemplate.opsForValue().get(BUILD_KEY + deep + "-" + id);
        if (build != null) {
            List<BuildingInfoDO> toList = JSONUtil.toList(JSONUtil.parseArray(build), BuildingInfoDO.class);
            log.info("从redis中获取到了小区等数据");
            return GeneralResponse.success(buildData(toList));
        }
        List<BuildingInfoDO> buildingInfoDOS = areaService.queryBuildingInfos(id, deep);
        if (CollUtil.isEmpty(buildingInfoDOS)) {
            redisTemplate.opsForValue().set("build" + deep + "-" + id, "-1", 5L, TimeUnit.SECONDS);
            return GeneralResponse.fail("-1", "未查询到小区信息", "");
        }
        Map<String, List<BuildingInfoDO>> map = buildingInfoDOS.stream().collect(Collectors.groupingBy(info -> info.getLevel() + "-" + info.getParentId()));
        map.forEach((k, v) -> redisTemplate.opsForValue().set(BUILD_KEY + k, JSONUtil.toJsonStr(v), 1L, TimeUnit.HOURS));
        return GeneralResponse.success(buildData(buildingInfoDOS));
    }

    private List<Map<String, Object>> buildData(List<BuildingInfoDO> toList) {
        return toList.stream().map(info -> {
            Map<String, Object> hashMap = new HashMap<>();
            hashMap.put("id", info.getId());
            hashMap.put("name", info.getName());
            hashMap.put("deep", info.getLevel());
            return hashMap;
        }).collect(Collectors.toList());
    }

}
